#include "wrapfunc.h"
#include "error.h"
#include "sockfunc.h"
#include <errno.h>
#include <arpa/inet.h>
#include <unistd.h>


int
Socket(int family, int type, int protocol) {
	int fd;
	if ((fd=socket(family, type, protocol)) < 0)
		error_dump("fail to create socket fd");
	return fd;
}

void
Bind(int fd, const struct sockaddr *sa, socklen_t salen) {
	if (bind(fd, sa, salen) < 0)
		error_dump("fail to bind");
}

void
Connect(int fd, const struct sockaddr *sa, socklen_t salen) {
	if (connect(fd, sa, salen) < 0)
		error_dump("fail to connect");
}

void
Listen(int fd, int backlog) {
	if (listen(fd, backlog) < 0)
		error_dump("fail to listen");
}

int
Accept(int fd, struct sockaddr *sa, socklen_t *salenptr) {
	int		client_fd;
AGAIN:
	if ((client_fd=accept(fd, sa, salenptr)) < 0) {
#ifdef	EPROTO
		if (errno == EPROTO || errno == ECONNABORTED)
#else
		if (errno == ECONNABORTED)
#endif
			goto AGAIN;
		else
			error_dump("fail to accept");
	}
	return client_fd;
}

void 
Shutdown(int fd, int how) {
	if (shutdown(fd, how) < 0)
		error_dump("fail to shutdown");
}

int 
Select(int nfds, fd_set *rset, fd_set *wset, fd_set *eset, struct timeval *timeout) {
	int n;
	if ((n=select(nfds, rset, wset, eset, timeout)) < 0)
		error_dump("fail to select");
	return n;
}

int 
Poll(struct pollfd *fds, nfds_t nfds, int timeout) {
	int n;
	if ((n=poll(fds, nfds, timeout)) < 0)
		error_dump("fail to poll");
	return n;
}

int
Getpeername(int fd, struct sockaddr *sa, socklen_t *salenptr) {
	int n;
	if ((n=getpeername(fd, sa, salenptr)) != 0)
		error_dump("fail to getpeername");
	return n;
}

ssize_t
Read(int fd, void *buf, size_t nbytes) {
	ssize_t n;
	if ((n=read(fd, buf, nbytes)) < 0)
		error_dump("fail to read");
	return n;
}

void 
Inet_pton(int af, const char *src, void *dst) {
	int n = inet_pton(af, src, dst);
	if (n == 0)
		error_quit("fail to inet_pton");
	else if (n < 0)
		error_dump("fail to inet_pton"); // set errno
}

void
Setsockopt(int fd, int level, int optname, const void *optvar, socklen_t optlen) {
    if (setsockopt(fd, level, optname, optvar, optlen) < 0)
        error_dump("fail to setsockopt");
}

void
Write(int fd, const void *buf, size_t nbytes) {
	ssize_t n;
	if ((size_t)(n=write(fd, buf, nbytes)) != nbytes)
		error_dump("fail to write");
}

void
Close(int fd) {
	if (close(fd) < 0)
		error_dump("fail to close fd");
}

ssize_t
Recvfrom(int fd, void *buf, size_t len, int flags, struct sockaddr *sa, socklen_t *salenptr) {
	ssize_t ret;
	if ((ret=recvfrom(fd, buf, len, flags, sa, salenptr)) < 0)
		error_dump("fail to recvfrom");
	return ret;
}

ssize_t
Sendto(int fd, const void *buf, size_t len, int flags, const struct sockaddr *sa, socklen_t salen) {
	ssize_t ret;
	if ((ret=sendto(fd, buf, len, flags, sa, salen)) < 0)
		error_dump("fail to sendto");
	return ret;
}

pid_t 
Fork() {
	pid_t pid = fork();
	if (pid == -1)
		error_dump("fail to fork");
	return pid;
}

int
Fcntl(int fd, int cmd, int arg) {
    int n = fcntl(fd, cmd, arg);
    if (n == -1)
        error_dump("fail to fcntl");
    return n;
}

int
Tcp_connect(const char *host, const char *service) {
	return tcp_connect(host, service);
}

int
Tcp_listen(const char *host, const char *service, int *addrlenp) {
	return tcp_listen(host, service, addrlenp);
}

int
Udp_client(const char *host, const char *service, struct sockaddr **saptr, socklen_t *lenptr) {
	return udp_client(host, service, saptr, lenptr);
}

int
Udp_connect(const char *host, const char *service) {
	return udp_connect(host, service);
}

int
Udp_server(const char *host, const char *service, socklen_t *lenptr) {
	return udp_server(host, service, lenptr);
}

